package com.advertisementsystem.Servie.Impl;

import com.advertisementsystem.Dto.LoginUser;
import com.advertisementsystem.Dto.PaymentDTO;
import com.advertisementsystem.Exception.BusinessException;
import com.advertisementsystem.Mapper.AdNegotiationMapper;
import com.advertisementsystem.Mapper.AdScheduleMapper;
import com.advertisementsystem.Mapper.PaymentMapper;
import com.advertisementsystem.Servie.*;
import com.advertisementsystem.entity.*;
import com.advertisementsystem.vo.PaymentVO;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private NegotiationService negotiationService;

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    private AdNegotiationMapper adNegotiationMapper;

    @Autowired
    private AdvertisementService advertisementService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private AdScheduleMapper adScheduleMapper;

    @Value("${payment.alipay.appId}")
    private String alipayAppId;

    @Value("${payment.alipay.privateKey}")
    private String alipayPrivateKey;

    @Value("${payment.alipay.publicKey}")
    private String publicKey;

    @Value("${payment.alipay.notifyUrl}")
    private String notifyUrl;

    @Value("${payment.alipay.returnUrl}")
    private String returnUrl;

    @Override
    public PaymentVO createPayment(PaymentDTO dto) {
        // 获取当前用户
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();

        // 获取协商信息
        AdNegotiation negotiation = adNegotiationMapper.selectById(dto.getNegotiationId());
        if (negotiation == null) {
            throw new BusinessException("协商记录不存在");
        }

        // 验证权限
        if (!negotiation.getAdvertiserId().equals(loginUser.getUser().getId())) {
            throw new BusinessException("无权为此协商创建支付");
        }

        // 验证协商状态
        if (negotiation.getStatus() != 1) {
            throw new BusinessException("只能为已达成的协商创建支付");
        }

        // 生成订单号
        String orderNo = generateOrderNo();

        // 创建支付记录
        Payment payment = new Payment();
        payment.setNegotiationId(dto.getNegotiationId());
        payment.setAdvertiserId(negotiation.getAdvertiserId());
        payment.setDeviceOwnerId(negotiation.getDeviceOwnerId());
        payment.setAmount(negotiation.getPrice());
        payment.setOrderNo(orderNo);
        payment.setStatus(0);
        payment.setPayMethod(dto.getPayMethod());
        payment.setCreatedTime(LocalDateTime.now());
        payment.setUpdatedTime(LocalDateTime.now());

        paymentMapper.insert(payment);

        // 根据支付方式生成支付参数
        String payParams = generatePayParams(payment);

        // 转换为VO
        PaymentVO vo = convertToVO(payment);
        vo.setPayParams(payParams);

        return vo;
    }

    private PaymentVO convertToVO(Payment payment) {
        if (payment == null) {
            return null;
        }

        PaymentVO vo = new PaymentVO();
        vo.setId(payment.getId());
        vo.setOrderNo(payment.getOrderNo());
        vo.setAmount(payment.getAmount());
        vo.setPayMethod(payment.getPayMethod());
        vo.setStatus(payment.getStatus());
        vo.setPayTime(payment.getPayTime());

        // 设置状态描述
        vo.setStatusDesc(convertStatusToDesc(payment.getStatus()));

        // 获取协商信息
        AdNegotiation negotiation = adNegotiationMapper.selectById(payment.getNegotiationId());
        if (negotiation != null) {
            // 设置广告信息
            Advertisement ad = advertisementService.getAdvertisementDetail(negotiation.getAdId());
            if (ad != null) {
                vo.setAdvertisementName(ad.getTitle());
            }

            // 设置设备信息
            Device device = deviceService.getDeviceDetail(negotiation.getDeviceId());
            if (device != null) {
                vo.setDeviceName(device.getName());
            }

            // 设置播放时段
            if (StringUtils.isNotBlank((CharSequence) negotiation.getTimeSlots())) {
                vo.setTimeSlots(negotiation.getTimeSlots());
            }
        }

        return vo;
    }

    private String convertStatusToDesc(Integer status) {
        if (status == null) {
            return "未知状态";
        }
        switch (status) {
            case 0:
                return "待支付";
            case 1:
                return "支付成功";
            case 2:
                return "支付失败";
            case 3:
                return "已退款";
            default:
                return "未知状态";
        }
    }

    @Override
    public void handlePaymentCallback(String orderNo, String transactionId, Integer status) {
        // 查询支付记录
        Payment payment = paymentMapper.findByOrderNo(orderNo);
        if (payment == null) {
            throw new BusinessException("支付订单不存在");
        }

        // 更新支付状态
        payment.setTransactionId(transactionId);
        payment.setStatus(status);
        payment.setPayTime(LocalDateTime.now());
        payment.setUpdatedTime(LocalDateTime.now());

        paymentMapper.updateById(payment);

        // 如果支付成功
        if (status == 1) {
            LambdaUpdateWrapper<Advertisement> UpdateWrapper = new LambdaUpdateWrapper<>();
            UpdateWrapper.eq(Advertisement::getId, payment.getAdvertiserId());
            UpdateWrapper.set(Advertisement::getStatus, 2);
            LambdaUpdateWrapper<Schedule>  scheduleLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            scheduleLambdaUpdateWrapper.eq(Schedule::getAdvertisementId, payment.getAdvertiserId());
            scheduleLambdaUpdateWrapper.eq(Schedule::getDeviceId,payment.getDeviceId());
            scheduleLambdaUpdateWrapper.set(Schedule::getStatus,"RUNNING");
            adScheduleMapper.update(null,scheduleLambdaUpdateWrapper);

        }
    }

    @Override
    public PaymentVO getPaymentStatus(String orderNo) {
        Payment payment = paymentMapper.findByOrderNo(orderNo);
        if (payment == null) {
            throw new BusinessException("支付订单不存在");
        }

        return convertToVO(payment);
    }
    /**
      * 获取支付历史记录
     *
             * @param pageNum 页码
     * @param pageSize 每页数量
     * @return 支付历史记录分页数据
     */
    @Override
    public IPage<PaymentVO> getPaymentHistory(Integer pageNum, Integer pageSize) {
        // 获取当前用户
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();

        // 构建分页对象
        Page<Payment> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        LambdaQueryWrapper<Payment> wrapper = new LambdaQueryWrapper<>();
        // 如果是广告主，只查看自己的支付记录
        wrapper.eq(Payment::getAdvertiserId, loginUser.getUser().getId())
                // 按创建时间倒序排序
                .orderByDesc(Payment::getCreatedTime);

        // 执行分页查询
        Page<Payment> paymentPage = paymentMapper.selectPage(page, wrapper);

        // 转换为VO分页对象
        Page<PaymentVO> voPage = new Page<>();
        // 复制分页信息
        BeanUtils.copyProperties(paymentPage, voPage, "records");

        // 转换记录列表
        List<PaymentVO> voList = paymentPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        voPage.setRecords(voList);

        return voPage;
    }

    private String generateOrderNo() {
        return "AD" + System.currentTimeMillis() +
                RandomStringUtils.randomNumeric(6);
    }

    private String generatePayParams(Payment payment) {
        if ("ALIPAY".equals(payment.getPayMethod())) {
            return generateAlipayParams(payment);
        } else if ("WECHAT".equals(payment.getPayMethod())) {
            return generateWechatPayParams(payment);
        }
        throw new BusinessException("不支持的支付方式");
    }

    private String generateAlipayParams(Payment payment) {
        // 构建支付宝支付参数
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do",
                alipayAppId,
                alipayPrivateKey,
                "json",
                "UTF-8",
                publicKey,
                "RSA2");

        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(notifyUrl);
        request.setReturnUrl(returnUrl);

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", payment.getOrderNo());
        bizContent.put("total_amount", payment.getAmount());
        bizContent.put("subject", "广告投放费用");
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

        request.setBizContent(bizContent.toString());

        try {
            return alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            log.error("Generate alipay params error", e);
            throw new BusinessException("生成支付参数失败");
        }
    }

    private String generateWechatPayParams(Payment payment) {
        // TODO: 实现微信支付参数生成
        throw new BusinessException("暂不支持微信支付");
    }
}